package main

import (
	"file-comparison-go/resolver"
	"file-comparison-go/utils"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

func main() {
	var srcPath string
	var targetPath string
	var srcMergePath string
	var targetMergePath string
	var isWrite bool
	var isSrcWrite bool
	var isTgtWrite bool
	var isNoDir, isZip, isJar bool
	flag.StringVar(&srcPath, "s", "", "源目录")
	flag.StringVar(&targetPath, "t", "", "目标目录")
	flag.StringVar(&srcMergePath, "sr", "", "源目录合成文件")
	flag.StringVar(&targetMergePath, "tr", "", "目标目录合成文件")
	flag.BoolVar(&isSrcWrite, "sw", false, "是否将源合成写入文件")
	flag.BoolVar(&isTgtWrite, "tw", false, "是否将目标合成写入文件")
	flag.BoolVar(&isWrite, "w", false, "是否将结果写入文件")
	flag.BoolVar(&isNoDir, "nd", false, "是否排除目录")
	flag.BoolVar(&isZip, "z", false, "是否解析压缩包")
	flag.BoolVar(&isJar, "j", false, "是否解析Jar包")
	flag.Parse()
	if srcPath == "" && srcMergePath == "" {
		fmt.Println("源目录不能为空")
		return
	}
	if targetPath == "" && targetMergePath == "" {
		fmt.Println("目标目录不能为空")
		return
	}
	threeDs := utils.New3DS()

	var targetFileResolve resolver.Resolver
	var srcFileResolve resolver.Resolver
	if len(targetMergePath) > 0 {
		targetFileResolve = resolver.NewMergeResolve(targetMergePath, isNoDir, isZip, isJar)
	} else {
		targetFileResolve = resolver.NewFileResolve(targetPath, isNoDir, isZip, isJar)
	}

	if len(srcMergePath) > 0 {
		srcFileResolve = resolver.NewMergeResolve(srcMergePath, isNoDir, isZip, isJar)
	} else {
		srcFileResolve = resolver.NewFileResolve(srcPath, isNoDir, isZip, isJar)
	}
	targetComparisonResolver, _ := targetFileResolve.Resolve()
	srcComparisonResolver, _ := srcFileResolve.Resolve()
	if srcComparisonResolver.FileType == resolver.FILE && targetComparisonResolver.FileType == resolver.FILE {
		targetComparisonFile := filepath.Base(targetComparisonResolver.RootPath)
		srcComparisonFile := filepath.Base(srcComparisonResolver.RootPath)
		for _, srcFile := range srcComparisonResolver.Files {
			srcFile.Path = strings.ReplaceAll(srcFile.Path, srcComparisonFile, targetComparisonFile)
		}
	}

	// 比对
	// 获取比对后的结果
	deleteFileInfos := make([]*resolver.FileInfo, 0)
	for _, srcFile := range srcComparisonResolver.Files {
		if targetFile, ok := targetComparisonResolver.FileMap[srcFile.Path]; ok {
			targetFile.OptType = 1
			if !targetFile.IsDir {
				if srcFile.Hash != targetFile.Hash {
					targetFile.OptType = 2
				}
			}
		} else {
			if _, ok := srcComparisonResolver.FileMap[srcFile.Path]; ok {
				deleteFileInfos = append(deleteFileInfos, srcFile)
			}
		}
	}

	addFileInfos := make([]*resolver.FileInfo, 0)
	updateFileInfos := make([]*resolver.FileInfo, 0)
	for _, targetFile := range targetComparisonResolver.Files {
		if _, ok := targetComparisonResolver.FileMap[targetFile.Path]; !ok {
			continue
		}
		if targetFile.OptType == 0 {
			addFileInfos = append(addFileInfos, targetFile)
		} else if targetFile.OptType == 2 {
			updateFileInfos = append(updateFileInfos, targetFile)
		} else if targetFile.OptType == 3 {
			deleteFileInfos = append(deleteFileInfos, targetFile)
		}
	}

	var msg string
	if len(deleteFileInfos) > 0 {
		msg += "删除如下：\n"
		for _, fi := range deleteFileInfos {
			msg += "    "
			msg += fi.ToString()
			msg += "\n"
		}
	}
	if len(addFileInfos) > 0 {
		msg += "新增如下：\n"
		for _, fi := range addFileInfos {
			msg += "    "
			msg += fi.ToString()
			msg += "\n"
		}
	}
	if len(updateFileInfos) > 0 {
		msg += "更新如下：\n"
		for _, fi := range updateFileInfos {
			msg += "    "
			msg += fi.ToString()
			msg += "\n"
		}
	}
	if msg == "" {
		msg += "没有文件变动"
	}
	if isWrite {
		writeFile, _ := os.Create("comparision-report.txt")
		defer writeFile.Close()
		writeFile.Write([]byte(msg))
	}

	if isSrcWrite {
		writeFile, _ := os.Create("src-report")
		defer writeFile.Close()
		var writtenMsg string = strconv.Itoa(int(srcComparisonResolver.FileType)) + resolver.Split + srcComparisonResolver.RootPath + "\n"
		for _, fi := range srcComparisonResolver.Files {
			writtenMsg += fi.ToAllString() + "\n"
		}
		writeFile.Write(threeDs.Encode([]byte(writtenMsg)))
	}

	if isTgtWrite {
		writeFile, _ := os.Create("tgt-report")
		defer writeFile.Close()
		var writtenMsg string = strconv.Itoa(int(targetComparisonResolver.FileType)) + resolver.Split + targetComparisonResolver.RootPath + "\n"
		for _, fi := range targetComparisonResolver.Files {
			writtenMsg += fi.ToAllString() + "\n"
		}
		writeFile.Write(threeDs.Encode([]byte(writtenMsg)))
	}

	fmt.Println(msg)
}
